package com.caineng.zhaobiao.zbapi.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import com.caineng.zhaobiao.zbapi.dao.CaiBaseUserDao;
import com.caineng.zhaobiao.zbapi.domain.CaiBaseUser;
import com.caineng.zhaobiao.zbapi.service.CainengApi;
import com.caineng.zhaobiao.zbapi.service.UserService;
import com.caineng.zhaobiao.zbapi.utils.AjaxResult;
import com.caineng.zhaobiao.zbapi.utils.JWTUtils;
import com.caineng.zhaobiao.zbapi.utils.MD5Util;
import com.caineng.zhaobiao.zbapi.utils.ZhaoBiaoCommon;
import com.caineng.zhaobiao.zbapi.utils.email.MyEmailUtil;
import com.caineng.zhaobiao.zbapi.utils.genID.IDUtils;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import com.mongodb.client.result.UpdateResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

/**
 * 用户信息管理模块
 * @author liandyao
 * @date 2022/7/30 13:56
 */
@Slf4j
@Api(tags = "用户接口")
@RestController
@RequestMapping("/zbapi/user")
public class UserController {

    @Autowired
    private UserService userService;


    @Autowired
    private CainengApi cainengApi;

    @Autowired
    private CaiBaseUserDao userDao;

    @Autowired
    private MyEmailUtil myEmailUtil;

    @Autowired
    private MongoTemplate mongoTemplate ;

    @ApiOperation(value = "根据id查询用户信息")
    @GetMapping("/getUserInfo")
    public AjaxResult getUserInfo(){
        String id = StpUtil.getLoginIdAsString();
        CaiBaseUser user = userService.findUserById(id);
        user.setPassword("");//隐藏密码
        return AjaxResult.success(user);
    }


    /**
     * 获取验证码
     * @param email
     * @return
     */
    @ApiOperationSupport(order = 33)
    @ApiOperation(value = "绑定邮箱--获取邮箱验证码")
    @GetMapping("/getEmailSms")
    public AjaxResult getEmailSms(String email){
        Assert.notNull(email,"邮箱不能为空");

        CaiBaseUser user = userService.findUserByEmail(email);
        if(user!=null){
            return AjaxResult.error("该邮箱已被其他用户绑定!");
        }

        boolean isFlag = myEmailUtil.sendEmailCode(email);
        if(isFlag){
            return AjaxResult.success("发送成功");
        }
        return AjaxResult.error("验证码发送失败");
    }

    /**
     * 获取验证码
     * @param email
     * @return
     */
    @ApiOperationSupport(order = 34)
    @ApiOperation(value = "绑定邮箱--校验邮箱验证码")
    @GetMapping("/checkEmailSms")
    public AjaxResult checkEmailSms(String email,String code){
        Assert.notNull(email,"邮箱不能为空");
        Assert.notNull(code,"验证码不能为空");

        boolean isFlag = myEmailUtil.checkEmailCode(email,code);
        if(isFlag){
            return AjaxResult.success("验证成功");
        }
        return AjaxResult.error("验证失败!");
    }



    /**
     * 获取验证码
     * @param phone
     * @param type 0 注册  1 修改密码
     * @return
     */
    @ApiOperation(value = "获取验证码 type==> 0 注册  1 修改密码 3 微信绑定手机")
    @GetMapping("/getSms")
    public AjaxResult getSms(String phone,Integer type){
        //注册
        if(type==0){
            CaiBaseUser userPo = userService.findUserByPhoneIgnoreDelFlag(phone);
            if(userPo==null){
                AjaxResult res = cainengApi.getSMS(phone);
                if(AjaxResult.OK_CODE.equals(res.getCode())){
                    return AjaxResult.success("验证码发送成功");
                }else{
                    return AjaxResult.error(res.getMsg());
                }
            }else if(userPo.getDelFlag()== ZhaoBiaoCommon.delFlag_YES){

                return AjaxResult.error(ZhaoBiaoCommon.DEL_FLAG_MSG);

            } else if(userPo.getDelFlag()== ZhaoBiaoCommon.delFlag_NO){
                return AjaxResult.error("该手机号码已注册!");

            }
        }else if(type==1){ //忘记密码
            AjaxResult res = cainengApi.getSMS(phone);
            if(AjaxResult.OK_CODE.equals(res.getCode())){
                return AjaxResult.success("验证码发送成功");
            }else{
                return AjaxResult.error(res.getMsg());
            }

        }else if(type==3){ //微信绑定手机
            CaiBaseUser userPo = userService.findUserByPhoneIgnoreDelFlag(phone);
            if(userPo!=null){
                if(userPo.getDelFlag()==ZhaoBiaoCommon.delFlag_YES){
                    return AjaxResult.error(ZhaoBiaoCommon.DEL_FLAG_MSG);
                }
                //如果是查询到有手机号码的用户,并且还没有被微信绑定,那么可以使用
                if(StrUtil.isBlank(userPo.getUnionid())){
                    AjaxResult res = cainengApi.getSMS(phone);
                    if(AjaxResult.OK_CODE.equals(res.getCode())){
                        return AjaxResult.success("验证码发送成功");
                    }else{
                        return AjaxResult.error(res.getMsg());
                    }
                }else{
                    return AjaxResult.error("该手机号码已经被其他用户绑定!");
                }
            }else{
                AjaxResult res = cainengApi.getSMS(phone);
                if(AjaxResult.OK_CODE.equals(res.getCode())){
                    return AjaxResult.success("验证码发送成功");
                }else{
                    return AjaxResult.error(res.getMsg());
                }

            }
        }
        return AjaxResult.error("验证码发送失败");
    }


    /**
     * 校验验证码
     * @param phone
     * @param code
     * @return
     */
    @ApiOperation(value = "校验验证码")
    @GetMapping("/checkSms")
    public AjaxResult checkSms(String phone,String code){
        AjaxResult res = cainengApi.checkSMS(phone,code);
        if(AjaxResult.OK_CODE.equals(res.getCode())){
            return AjaxResult.success("验证码正确");
        }else{
            return AjaxResult.error(res.getMsg());
        }
    }

    @ApiOperation(value = "修改密码")
    @PostMapping("/updatePassword")
    public AjaxResult updatePassword(String oldPassword,String newPassword){
        String userId = StpUtil.getLoginIdAsString();
        CaiBaseUser user = userService.findUserById(userId);
        //原密码为空的情况
        if(StrUtil.isBlank(user.getPassword())){
            user.setPassword(MD5Util.encode(newPassword));
            userDao.save(user);
            return AjaxResult.success("修改成功");
        }else{
            if(StrUtil.equals(MD5Util.encode(oldPassword),user.getPassword())){
                user.setPassword(MD5Util.encode(newPassword));
                userDao.save(user);
                return AjaxResult.success("修改成功");
            }else{
                return AjaxResult.error("原密码错误");
            }
        }

    }

    @ApiOperation(value = "修改个人信息")
    @PostMapping("/updateInfo")
    public AjaxResult updateInfo(CaiBaseUser vo, String verifyCode){
        String userId = StpUtil.getLoginIdAsString();

        //正在保存手机号码
        if(StrUtil.isNotBlank(vo.getPhone()) && StrUtil.isNotBlank(verifyCode)){
            AjaxResult aj=checkSms(vo.getPhone(),verifyCode);
            if(AjaxResult.OK_CODE.equals(aj.getCode())){
                CaiBaseUser user = userService.findUserById(userId);
                user.setPhone(vo.getPhone());
                if(StrUtil.isNotBlank(vo.getHeadImg())) {
                    user.setHeadImg(vo.getHeadImg());
                }
                userDao.save(user);
                return AjaxResult.success("修改成功");
            }else{
                return aj ;
            }
        }else{
            CaiBaseUser user = userService.findUserById(userId);
            user.setEmail(vo.getEmail());//修改邮箱
            user.setShowName(vo.getShowName()); //修改个人账号
            if(StrUtil.isNotBlank(vo.getHeadImg())) {
                user.setHeadImg(vo.getHeadImg());
            }
            userDao.save(user);
            return AjaxResult.success("修改成功");
        }

    }

    @ApiOperation(value = "忘记密码")
    @PostMapping("/forgot")
    public AjaxResult forgot(CaiBaseUser vo,String verifyCode){
        log.info("+======"+vo.getPhone()+"   "+verifyCode);
        //正在保存手机号码
        if(StrUtil.isNotBlank(vo.getPhone()) && StrUtil.isNotBlank(verifyCode)){
            AjaxResult aj=checkSms(vo.getPhone(),verifyCode);
            if(AjaxResult.OK_CODE.equals(aj.getCode())){
                CaiBaseUser user = userService.findUserByPhone(vo.getPhone());
                if(user==null){
                    //直接给他注册一个账号
                    user = new CaiBaseUser();
                    user.setId(IDUtils.getID());
                    user.setCreateTime(DateUtil.now());
                    user.setPassword(MD5Util.encode(vo.getPassword()));
                    userDao.insert(user);//保存到mongodb数据库
                    return AjaxResult.success("保存成功");
                }
                user.setPassword(MD5Util.encode(vo.getPassword()));
                userDao.save(user);
                return AjaxResult.success("修改成功");
            }else{
                return aj ;
            }
        }
        return AjaxResult.error("修改失败");
    }

    @ApiOperation(value = "加入设备型号和设备id")
    @PostMapping("/saveClientId")
    public AjaxResult saveClientId(String clientId, String clientType){
        if(StpUtil.isLogin()) {
            String userId = StpUtil.getLoginIdAsString();
            Query query = Query.query(Criteria.where("userId").is(userId)) ;
            Update update = new Update();
            update.set("clientId", clientId);
            update.set("clientType",clientType);
            update.set("userId",userId);
            update.set("lastLoginTime",System.currentTimeMillis()/1000);
            //upsert 如果存在就修改,如果不存在就增加属性
            UpdateResult result = mongoTemplate.upsert(query,update,"cai_base_user_extend");
            return AjaxResult.success("成功");
        }
        return AjaxResult.success("当前未登录,不记录本次提交的数据");
    }


    @ApiOperation(value = "获取uni-im登录的token")
    @PostMapping("/getUniImJwtToken")
    public AjaxResult getUniImJwtToken(){
        String userId = StpUtil.getLoginIdAsString();
        CaiBaseUser user = userService.findUserById(userId);
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("openid", user.getId());
        map.put("nickname",user.getShowName());

        //头像对象
        Map mapAvatar = new HashMap();
        mapAvatar.put("url",user.getHeadImg());
        map.put("avatar_file",mapAvatar);

        map.put("role",new String[]{"user_uni_im"});
        String sign = JWTUtils.createJwt(map);
        log.info("签名的结果:"+sign);
        return AjaxResult.success("成功",sign);
    }


    @ApiOperation(value = "判断是否是uniIm的管理员 才才和能能")
    @PostMapping("/uniImAdmin")
    public AjaxResult uniImAdmin(){
        String userId = StpUtil.getLoginIdAsString();
        log.info("登录的id是:"+userId);
        JSONObject map = new JSONObject();

        if("10001".equals(userId) || "10000".equals(userId)){
            map.putOpt("isAdmin",1);
        }
        map.putOpt("adminId",new String[]{"63da177fe1a35c9969ddc47b","63da180d819ce8248ef969f2"});
        return AjaxResult.success("成功",map);
    }

    public static void main(String[] args) {
        //密码加密
        String s = MD5Util.encode("newability2021");
        System.out.println(s);
    }
}
